import { $event, $preload } from '@/cross/utils';
import { pageStore } from '@/pages/editor/store/page';
import { project } from '@alilc/lowcode-engine';
import { IPublicEnumTransformStage } from '@alilc/lowcode-types';
import {
  checkCharacterNoStartWithACharacter,
  checkIsMedia,
  checkSeparatorInString,
  parsingCss,
  replaceSeparators,
} from './parsingCss';

class CssAdapterUtil {
  scope = '__main';
  /*
   * 转换为Css
   */
  convertToCss(cssList, isPreview) {
    // 什么场景需要用到children
    // 1 伪类
    // 2 媒体查询
    // 什么是root
    // 1. #xxx / .xxx / xxx

    let css = '';
    function convertNodeToCss(node, parentNode?: any, lastOne?: any) {
      if (node.selector && (!parentNode || parentNode.selector)) {
        const cssCode = this.props.helper?.utils?.invoke?.('parseToCssCode', node.style) || '';
        // 处理媒体查询
        if (checkIsMedia(node.selector)) {
          if (!isPreview) {
            css += node.selector + ' {\n';
          }
        } else {
          // class 节点
          let selectorText = this.getNodeClassname(node, parentNode, isPreview);

          css += cssCode.replace('#main', selectorText);
          // 判断父级是否为媒体查询
          const parentNodeIsMedia = checkIsMedia(parentNode?.selector);
          // 判断父级是否为Normal Custom Selector .primary:hover
          const parentNodeIsNormal = checkSeparatorInString(parentNode?.selector);
          if (isPreview && parentNode && !parentNodeIsMedia && !parentNodeIsNormal) {
            // 媒体查询时不追加伪类实体
            let selectorText2 = this.getNodeClassname(node, parentNode, false);
            if (selectorText2[0] === '.') {
              selectorText2 = selectorText2.replace('.', this.state.scope + '__');
              selectorText2 = '.' + selectorText2;
            }
            css += cssCode.replace('#main', selectorText2);
          }
        }

        // 媒体查询增加后大括号
        if (!isPreview && lastOne && checkIsMedia(parentNode.selector)) {
          css += '}\n';
        }

        // if (isPreview) {
        // child-preview
        // const selectorText = this.getNodeClassname(node, parentNode, true, true);
        // css += cssCode.replace('#main', (isPreview ? `.${scope}__` : '') + selectorText);
        // }
      }
      // 子节点
      if (node?.children?.length > 0) {
        node.children.forEach((item, index) => {
          convertNodeToCss(item, node, node.children.length - 1 === index);
        });
      }
    }
    cssList.forEach((_) => convertNodeToCss(_));
    // console.log(css)
    return css;
  }

  heckCharacterNoStartWithACharacter(input) {
    if (!input) return false;
    const trimmedInput = input.trim();
    const firstChar = trimmedInput.charAt(0);
    const punctuationRegex = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/;
    return !punctuationRegex.test(firstChar);
  }

  refreshPreviewState(helper) {
    // const store = helper?.getStore();
    const projectSchema = project.exportSchema(IPublicEnumTransformStage.Save);
    const docSchema = project.currentDocument.exportSchema(IPublicEnumTransformStage.Save);
    // const projectSchema = store.currentProject.schema;
    // const docSchema = store.currentFile.schema;
    // this.utils.previewRendering(projectSchema.css + '\n' + docSchema.css);
    return {
      // @ts-ignore
      cssList: docSchema.cssList || [],
      // @ts-ignore
      cssListGlobal: projectSchema.cssList || [],
    };
  }

  /*
   * 预览器渲染
   */
  previewRendering(cssCode) {
    this.previewRendering(cssCode);
  }

  /*
   * 计算节点className
   */
  getNodeClassname(node, parentNode?: any, isPreview?: boolean, isGetNodeAttr?: boolean) {
    // if (!(node.selector === '@media (max-width: 600px)' || parentNode?.selector === '@media (max-width: 600px)')) return '';
    // console.log('getNodeClassname:', node.selector, parentNode?.selector);
    if (!node) return '';

    let prefix = parentNode
      ? `${checkCharacterNoStartWithACharacter(parentNode.selector) ? '.' : ''}${
          parentNode.selector
        }`
      : '';

    let nodeSelector = isPreview && parentNode ? node.selector.replace(':', '') : node.selector;

    // 检测父级是否为Normal
    if (parentNode && checkSeparatorInString(parentNode.selector)) {
      if (isPreview) {
        // nodeSelector = nodeSelector.replace('')
        // 转换父级的特殊字符
        prefix = prefix.replace('@', '__').replaceAll('(', '__').replaceAll(')', '__');
        // 补充类选择器
        if (checkIsMedia(parentNode.selector)) {
          prefix = '.' + prefix;
        }
        // 子节点像父级一样转换
        nodeSelector = replaceSeparators(nodeSelector).replaceAll('.', '__');
      } else {
        nodeSelector = ' ' + nodeSelector;
      }
    }

    // 父级是媒体查询则不设置父级前缀，因为是嵌套关系
    if (parentNode && checkIsMedia(parentNode.selector)) {
      if (isPreview) {
        // nodeSelector = replaceSeparators(nodeSelector).replaceAll('.', '__');
      } else {
        prefix = '';
      }
    }

    let nodeSelectorPrefix = checkCharacterNoStartWithACharacter(node.selector) ? '.' : '';
    // 特殊情况动画keyframes下的 0% ，100% 要去掉前面的 .
    if (parentNode?.selector?.includes('@keyframes')) {
      nodeSelectorPrefix = '';
    }
    let selectorText = `${prefix}${
      isPreview && prefix ? '___' : ''
    }${nodeSelectorPrefix}${nodeSelector}`;

    // 判断情况
    // @media ()...

    if (isPreview) {
      // normal .class span | .class .xxx
      if (checkSeparatorInString(selectorText)) {
        selectorText = replaceSeparators(selectorText);
      }
      if (selectorText[0] === '.') {
        selectorText = selectorText.replace('.', this.scope + '__');
        if (!isGetNodeAttr) {
          selectorText = '.' + selectorText;
        }
      }
      // #
    }
    if (isGetNodeAttr && parentNode) {
      // 实现调试态继承
      selectorText = this.getNodeClassname(parentNode, undefined, true, true) + ' ' + selectorText;
    }
    return selectorText;
  }

  /*
   * 刷新预览态
   */
  // refreshPreviewState() {
  //   const css = this.convertToCss(this.state.cssList, true);
  //   const globalCss = this.convertToCss(this.state.cssListGlobal, true);
  //   this.previewRendering(css + '\n' + globalCss);
  // }

  /*
   * 保存
   */
  saveCss({
    globalIsChange,
    transform,
    stateCssList = [],
    stateCssListGlobal = [],
  }: {
    globalIsChange?: boolean;
    transform?: boolean;
    stateCssList?: any[];
    stateCssListGlobal?: any[];
  } = {}) {
    const store = pageStore;
    const bindNowClassName = [];
    const cssList = stateCssList.map((_) => {
      if (_.__replaceStyleAndAutoBindClassNameToNode) {
        bindNowClassName.push(_.selector);
        delete _.__replaceStyleAndAutoBindClassNameToNode;
      }
      return _;
    });
    const cssListGlobal = stateCssListGlobal.map((_) => {
      if (_.__replaceStyleAndAutoBindClassNameToNode) {
        bindNowClassName.push(_.selector);
        delete _.__replaceStyleAndAutoBindClassNameToNode;
      }
      return _;
    });
    const css = this.convertToCss(cssList, false);
    // return console.log('css: ', css);
    const globalCss = this.convertToCss(cssListGlobal, false);
    if (store) {
      const nodeId = project.currentDocument?.selection?.node?.id;
      store.updateDocumentSchema({
        // @ts-ignore
        cssList,
        css,
      });
      if (globalIsChange) {
        store.updateProjectSchema({
          // @ts-ignore
          cssList: cssListGlobal,
          css: globalCss,
        });
      }
      setTimeout(() => {
        if (nodeId) {
          $preload('OPEN_CSS_SETTER_POPUP', true);
          $preload('bindNowClassName', bindNowClassName);
          const node = project.currentDocument?.getNodeById(nodeId);
          if (transform) node?.setPropValue('style', undefined);
          node?.select?.();
          // @ts-ignore
          document.getElementsByClassName('next-tabs-tab-inner')?.[1]?.click?.();
        }
        setTimeout(() => {
          $event.$emit('REFRESH_CSS_SETTER', {
            cssList,
            cssListGlobal,
          });
          // 刷新（因为存在样式修改不更新的情况）
          project?.simulatorHost.rerender();
        }, 100);
      }, 50);
    }
    // this.props.emitClose?.();
  }

  /*
   * 解析css
   */
  parsingCss(
    cssCode,
    {
      fileName,
      type,
      stateCssList,
      stateCssListGlobal,
    }: {
      fileName?: string;
      type?: 'Component' | 'Global';
      stateCssList?: any[];
      stateCssListGlobal?: any[];
    } = {},
  ) {
    try {
      const documentSchema = fileName ? project.getDocumentByFileName(fileName) : null;
      const projectSchema =
        type === 'Component' ? null : project.exportSchema(IPublicEnumTransformStage.Save);
      const sourceCssList =
        type === 'Component'
          ? stateCssList || (documentSchema as any)?.cssList
          : stateCssListGlobal || (projectSchema as any).cssList;
      const cssList = parsingCss(cssCode, {
        existCssList: sourceCssList,
      });
      return cssList;
    } catch (e) {
      console.error(e);
    }
  }
}

const cssAdapter = new CssAdapterUtil();
export default cssAdapter;
